import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
import statsmodels.api  as sm 

# 设置随机种子保证可重复性
np.random.seed(42)

# ======================
# 1. 生成模拟数据集
# ======================
n_samples = 100

# 生成自变量
X1 = np.random.normal(5, 1.5, n_samples)  # 均值为5，标准差1.5的正态分布
X2 = 0.7 * X1 + np.random.normal(0, 0.5, n_samples)  # 与X1相关的变量
X3 = np.random.uniform(2, 8, n_samples)  # 均匀分布变量

# 生成因变量（含噪声）
y = 2.5 * X1 + 1.8 * X2 - 3.2 * X3 + np.random.normal(0, 2, n_samples)

# 创建数据框
df = pd.DataFrame({'X1': X1, 'X2': X2, 'X3': X3, 'y': y})

print("数据集前5行：")
print(df.head())

# ======================
# 2. 一元线性回归（X1与y）
# ======================
# 使用statsmodels进行详细回归分析
X_single = sm.add_constant(df['X1'])  # 添加常数项
model_single = sm.OLS(df['y'], X_single)
results_single = model_single.fit()

print("\n一元回归结果：")
print(results_single.summary())

# 可视化结果
plt.figure(figsize=(10, 5))
plt.scatter(df['X1'], df['y'], alpha=0.7)
plt.plot(df['X1'], results_single.predict(X_single), color='red')
plt.title('一元线性回归 (X1 -> y)')
plt.xlabel('X1')
plt.ylabel('y')
plt.show()

# ======================
# 3. 多元线性回归（X1,X2,X3与y）
# ======================
X_multi = sm.add_constant(df[['X1', 'X2', 'X3']])
model_multi = sm.OLS(df['y'], X_multi)
results_multi = model_multi.fit()

print("\n多元回归结果：")
print(results_multi.summary())

# ======================
# 4. 主成分分析（PCA）
# ======================
# 标准化数据
scaler = StandardScaler()
X_scaled = scaler.fit_transform(df[['X1', 'X2', 'X3']])

# 执行PCA
pca = PCA(n_components=3)
principal_components = pca.fit_transform(X_scaled)

# 创建主成分数据框
pca_df = pd.DataFrame(
    data = principal_components,
    columns = ['PC1', 'PC2', 'PC3']
)

print("\n主成分分析结果：")
print(f"解释方差比: {pca.explained_variance_ratio_}")

# 可视化PCA结果
plt.figure(figsize=(12, 5))

# 碎石图
plt.subplot(1, 2, 1)
plt.plot(range(1,4), pca.explained_variance_ratio_.cumsum(), marker='o')
plt.xlabel('主成分数量')
plt.ylabel('累计解释方差比例')
plt.title('碎石图')

# 主成分散点图
plt.subplot(1, 2, 2)
plt.scatter(pca_df['PC1'], pca_df['PC2'], alpha=0.7)
plt.xlabel('PC1 (%.2f%%)' % (pca.explained_variance_ratio_[0]*100))
plt.ylabel('PC2 (%.2f%%)' % (pca.explained_variance_ratio_[1]*100))
plt.title('主成分空间分布')

plt.tight_layout()
plt.show()